package com.yunhe.abnormal.repository.base;

import com.yunhe.abnormal.domain.base.AbnormalRule;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@Repository
public interface AbnormalRuleRepository extends Neo4jRepository<AbnormalRule, Long> {

    AbnormalRule findByName(String name);

    @Query("match (obj)-[r:HAS_ABNORMAL_RULE]->(ar:AbnormalRule) where ID(ar)={ruleId} delete r")
    void unbindAbnormalRule(@Param("ruleId") Long abnormalRuleId);

    @Query("match (obj), (ar:AbnormalRule) where ID(obj)={objectId} and ID(ar)={ruleId} create (obj)-[:HAS_ABNORMAL_RULE]->(ar)")
    void bindAbnormalRule(@Param("ruleId") Long abnormalRuleId, @Param("objectId") Long objectId);

    @Query("match (ar:AbnormalRule)-[r:ALARM_LEVEL_OF]->(al:AlarmLevel) where ID(ar) = {ruleId} delete r")
    void deleteAlarmLevelRelationship(@Param("ruleId") Long abnormalRuleId);

    @Query("match (ar:AbnormalRule),(al:AlarmLevel) where ID(ar) = {ruleId} and ID(al) = {levelId} " +
            "create (ar)-[:ALARM_LEVEL_OF{formula:{formula},measPointNumberStr:{measPointNumberStr},measPointNumbers:{measPointNumbers}," +
            "relatedPointNumbers:{relatedPointNumbers},description:{description}}]->(al)")
    void createAlarmLevelRelationship(@Param("ruleId") Long abnormalRuleId,
                                      @Param("levelId") Long alarmLevelId,
                                      @Param("formula") String formula,
                                      @Param("measPointNumberStr") String measPointNumberStr,
                                      @Param("measPointNumbers") List<Long> measPointNumbers,
                                      @Param("relatedPointNumbers") List<Long> relatedPointNumbers,
                                      @Param("description") String description);

    @Query("match (s:Station)-[*0..4]->(ar:AbnormalRule) where ID(ar)={id} return ID(s) limit 1")
    Long getStationIdByAbnormalRuleId(@Param("id") Long id);

    @Query("match(s:Station)-[:HAS_ABNORMAL_RULE]->(ar:AbnormalRule)" +
            " return ID(s) as stationId,ID(ar) as id,ar.name as name,ar.title as title,ID(s) as objectId,s.title as objectTitle,ar.sn as sn" +
            " union all match(s:Station)-[:HAS_RESOURCE]->(e:EnergyUnit)-[:HAS_ABNORMAL_RULE]->(ar:AbnormalRule)" +
            " return ID(s) as stationId,ID(ar) as id,ar.name as name,ar.title as title,ID(e) as objectId,e.title as objectTitle,ar.sn as sn" +
            " union all match(s:Station)-[:HAS_RESOURCE]->(d:Device)-[:HAS_ABNORMAL_RULE]->(ar:AbnormalRule)" +
            " return ID(s) as stationId,ID(ar) as id,ar.name as name,ar.title as title,ID(d) as objectId,d.title as objectTitle,ar.sn as sn" +
            " union all match(s:Station)-[:HAS_RESOURCE]->(:EnergyUnit)-[:CONTAINS]->(d:Device)-[:HAS_ABNORMAL_RULE]->(ar:AbnormalRule)" +
            " return ID(s) as stationId,ID(ar) as id,ar.name as name,ar.title as title,ID(d) as objectId,d.title as objectTitle,ar.sn as sn")
    List<Map<String, String>> getRuleDtoMap();

    @Query("match (obj)-[:HAS_ABNORMAL_RULE]->(ar:AbnormalRule) where ID(ar )={id} return ID(obj) limit 1")
    Long getRelatedObjectIdByAbnormalRuleId(@Param("id") Long id);

    @Query(" start f=node({id}) return labels(f)[0]")
    String getLabelName(@Param("id") Long id);

    @Query("match (ar:AbnormalRule),(a:Analog),(p:PointDataType) where ID(ar)={ruleId} and ID(a)={analogId} and ID(p)={pdtId} " +
            "create (ar)-[:HAS_ANALOG{terminal:{terminalTitle}}]->(a)-[:POINTDATATYPE_OF]->(p)")
    void createAnalogRelationship(@Param("ruleId") Long ruleId,
                                  @Param("analogId") Long analogId,
                                  @Param("pdtId") Long pdtId,
                                  @Param("terminalTitle") String terminalTitle);
}
